package com.frame.work.common.util;


import org.apache.commons.lang3.StringUtils;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 数据帧拼接工具
 *
 * @author wjming
 */
public class CmdUtils {
    private static Pattern pattern = Pattern.compile("[0-9]*");
    private static String V$ = "$";

    private static final String CMD_2A = "2A";
    private static final String CMD_23 = "23";
    private static final Integer HEX_01 = 0x01;
    private static final int TWO = 2;
    private static final int FOUR = 4;
    private static final int EIGHT = 8;
    private static final int NINE = 9;

    /**
     * 计算指令长度
     *
     * @param body
     * @return
     */
    public static String getDateLength(String body) {
        return intToHexTwo(body.length() / 2);
    }

    /**
     * 计算长数据帧指令长度
     *
     * @param body
     * @return
     */
    public static String getDateLength2(String body) {
        int ff = 255;
        int length = body.length() / TWO;
        if (body.length() / TWO >= ff) {
            return "FF" + intToHexTwo(length - 255);
        } else {
            return intToHexTwo(body.length() / TWO);
        }

    }


    /**
     * 十进制转十六进制
     * 两位
     *
     * @param dec
     * @return
     */
    public static String intToHexTwo(int dec) {
        String hex = "";
        if (dec == 0) {
            hex = "00";
        } else {
            String str = Integer.toHexString(dec);
            if ((str.length() & HEX_01) == 1) {
                str = '0' + str;
            }
            hex = hex + str;
        }

        return hex.toUpperCase();
    }

    public static String intToHexFour(int dec) {
        String hex = "";
        if (dec == 0) {
            hex = "0000";
        } else {
            String str = Integer.toHexString(dec);
            if ((str.length() & HEX_01) == 1) {
                str = '0' + str;
            }
            hex = hex + str;
        }

        if (hex.length() == TWO) {
            hex = "00" + hex;
        }

        return hex.toUpperCase();
    }

    /**
     * 十进制转16禁止高位补零
     *
     * @param dec
     * @return
     */
    public static String intTo16(long dec) {
        String hex = "";
        if (dec == 0) {
            hex = "0000000000000000";
        } else {
//            String str = Long.toHexString(dec);
            hex = String.format("%016x", dec);
        }
        return hex.toUpperCase();
    }


    /**
     * 计算和校验值
     *
     * @param body
     * @return
     */
    public static String getCmdBodySum(String body) {
        int sum = 0;
        for (int i = 0; i < body.length(); i += TWO) {
            sum += Integer.parseInt(body.substring(i, i + 2), 16);
        }
        sum = sum & 0xff;
        String hexStr = Integer.toHexString(sum);
        if (hexStr.length() == 1) {
            hexStr = "0" + hexStr;
        }
        return hexStr.toUpperCase();
    }


    /**
     * 静音窗帘和校验计算
     */
    public static String getCmdBodySumCurtains(String body) {
        int sum = 0;
        for (int i = 0; i < body.length(); i += TWO) {
            sum += Integer.parseInt(body.substring(i, i + 2), 16);
        }
        sum = sum & 0xffff;
        sum = 0x2017 + sum;
        String hexStr = Integer.toHexString(sum);

        StringBuffer sb = new StringBuffer("");
        sb.append(hexStr.substring(2, 4));
        sb.append(hexStr.substring(0, 2));

        return sb.toString().toUpperCase();
    }


    /**
     * 得到十六进制数的静态方法
     *
     * @param decimalNumber 十进制数
     * @return 四位十六进制数字符串
     */
    public static String getHexString(int decimalNumber) {
        StringBuilder sb = new StringBuilder();
        //将十进制数转为十六进制数
        String hex = Integer.toHexString(decimalNumber);
        sb.append(hex);
        //加长到四位字符，用0补齐
        while (sb.length() < FOUR) {
            sb.insert(0, "0");
        }
        return sb.toString().toUpperCase();

    }

    /**
     * 得到十六进制数的静态方法
     *
     * @param decimalNumber 十进制数
     * @return 八位十六进制数字符串
     */
    public static String getHexEightString(int decimalNumber) {
        StringBuilder sb = new StringBuilder();
        //将十进制数转为十六进制数
        String hex = Integer.toHexString(decimalNumber);
        sb.append(hex);
        //加长到八位字符，用0补齐
        while (sb.length() < EIGHT) {
            sb.insert(0, "0");
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 四位数据帧高地位替换
     * 高位编程低位，低位变高位
     *
     * @param br
     * @return
     */
    public static String getHighPositionReplacement(String br) {
        String subSta = StringUtils.substring(br, 0, 2);
        String subEnd = StringUtils.substring(br, 2, 4);
        String sub = subEnd + subSta;
        return sub;
    }


    /**
     * 百分数转小数
     */
    public static Double getDoubleNum(String percentage) {
        //百分比转换为小数
        Double aDouble = null;
        String per0 = "0";
        String symbol = "%";
        String zeroSpot = "0.";
        if (StringUtils.startsWith(percentage, zeroSpot)) {
            aDouble = Double.valueOf(percentage);
        } else if (StringUtils.endsWith(percentage, symbol)) {
            percentage = percentage.replace(symbol, "");
            aDouble = Double.valueOf(percentage) / 100;
        } else if (!per0.equals(percentage) && pattern.matcher(percentage).matches()) {
            aDouble = Double.valueOf(Integer.valueOf(percentage)) / 100;
        } else {
            aDouble = 0.0;
        }
        return aDouble;
    }


    /**
     * @param: [content]
     * @return: int
     * @description: 十六进制转十进制
     */
    public static int covert16To10(String content) {
        int number = 0;
        int number10 = 10;
        String[] highLetter = {"A", "B", "C", "D", "E", "F"};
        Map<String, Integer> map = new HashMap<>(5);
        for (int i = 0; i <= NINE; i++) {
            map.put(i + "", i);
        }
        for (int j = 10; j < highLetter.length + number10; j++) {
            map.put(highLetter[j - 10], j);
        }
        String[] str = new String[content.length()];
        for (int i = 0; i < str.length; i++) {
            str[i] = content.substring(i, i + 1);
        }
        for (int i = 0; i < str.length; i++) {
            number += map.get(str[i]) * Math.pow(16, str.length - 1 - i);
        }
        return number;
    }


    /**
     * 字符串 00 00 00 00 00 00 FF FF 转化为实际二进制byte[]数据byte[8]
     *
     * @param hex
     * @return
     */
    public static byte[] hexStr2Byte(String hex) {
        ByteBuffer bf = ByteBuffer.allocate(hex.length() / 2);
        for (int i = 0; i < hex.length(); i++) {
            String hexStr = hex.charAt(i) + "";
            i++;
            hexStr += hex.charAt(i);
            byte b = (byte) Integer.parseInt(hexStr, 16);
            bf.put(b);
        }
        return bf.array();
    }

    /**
     * 获取byte[]数组中的数据读取方式:从高位到低位
     * 以外机为1举例,外机1获取道德byte数据是byte[6],byte[7] 组合成16个字节即:
     * 1000 0000 0000 0000
     * 从做左边的1开始
     * 这个数据中所表示的空调位置就是[1_15]
     * 1100 0000 0000 0000
     * 这个数据中所表示的空调位置就是[1_15,1_14]
     * 1100 0000 0000 0001
     * 这个数据中所表示的空调位置就是[1_15,1_14,1_0]
     *
     * @param b
     * @return
     */
    public static List<String> byteToBit(byte b, int y) {
        List<String> addressList = new ArrayList<>(16);
        for (int i = 7; i >= 0; i--) {
            byte b1 = (byte) ((b >> i) & 0x1);
            if (b1 != 0) {

                if (y >= 0 && y < 2) {
                    if (y % 2 != 0) {
                        addressList.add("4_0" + i);
                    }
                    if (y % 2 == 0) {
                        addressList.add("4_" + (8 + i));
                        if (8 + i < 10) {
                            addressList.add("4_0" + (8 + i));
                        } else {
                            addressList.add("4_" + (8 + i));
                        }
                    }
                }
                if (y >= 2 && y < 4) {
                    if (y % 2 != 0) {
                        addressList.add("3_0" + i);
                    }
                    if (y % 2 == 0) {
                        if (8 + i < 10) {
                            addressList.add("3_0" + (8 + i));
                        } else {
                            addressList.add("3_" + (8 + i));
                        }
                    }
                }
                if (y >= 4 && y < 6) {
                    if (y % 2 != 0) {
                        addressList.add("2_0" + i);
                    }
                    if (y % 2 == 0) {
                        if (8 + i < 10) {
                            addressList.add("2_0" + (8 + i));
                        } else {
                            addressList.add("2_" + (8 + i));
                        }

                    }
                }

                if (y >= 6 && y < 8) {
                    if (y % 2 != 0) {
                        addressList.add("1_0" + i);
                    }
                    if (y % 2 == 0) {
                        if (8 + i < 10) {
                            addressList.add("1_0" + (8 + i));
                        } else {
                            addressList.add("1_" + (8 + i));
                        }

                    }
                }

            }
        }

        return addressList;
    }
}
